﻿using System;
using System.Collections.Generic;
using System.Windows.Input;
using System.Runtime.InteropServices;
using System.Windows.Interop;
using System.Windows;
using System.ComponentModel;

namespace MainUI
{
    public static class HotkeyManager
    {
        [DllImport("user32.dll")]
        private static extern bool RegisterHotKey(IntPtr hWnd, int id, uint fsModifiers, uint vk);

        [DllImport("user32.dll")]
        private static extern bool UnregisterHotKey(IntPtr hWnd, int id);

        private static HwndSource _source;
        private static int _hotkeyIdCounter = 0x0000;

        public static void Initialize(Window window)
        {
            var handle = new WindowInteropHelper(window).EnsureHandle();
            _source = HwndSource.FromHwnd(handle);
            _source.AddHook(HwndHook);
        }

        public static int Register(ModifierKeys modifiers, Key key, Action callback)
        {
            var id = ++_hotkeyIdCounter;
            var virtualKey = KeyInterop.VirtualKeyFromKey(key);

            try
            {
                if (!RegisterHotKey(_source.Handle, id, (uint)modifiers, (uint)virtualKey))
                {
                    int error = Marshal.GetLastWin32Error();
                    throw new Win32Exception(error, $"热键注册失败 (错误码: 0x{error:X8})");
                }
            }
            catch (Win32Exception ex)
            {

            }

            _callbacks[id] = callback;
            return id;
        }

        public static void Unregister(int id)
        {
            if (_callbacks.ContainsKey(id))
            {
                UnregisterHotKey(_source.Handle, id);
                _callbacks.Remove(id);
            }
        }

        private static readonly Dictionary<int, Action> _callbacks = new Dictionary<int, Action>();

        private static IntPtr HwndHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            const int WM_HOTKEY = 0x0312;
            if (msg == WM_HOTKEY)
            {
                int id = wParam.ToInt32();
                if (_callbacks.TryGetValue(id, out Action callback))
                {
                    callback();
                    handled = true;
                }
            }
            return IntPtr.Zero;
        }
    }
}
